#include "mempool.h"
#include "stdlib.h"
#include <assert.h>



/**
 * @brief mempool init
 * @param pool the pool pointer 
 * @param blockSize the memory unit size (>= 4 byte)
 * @param blockCount the count of pool (> 1)
 * @retval None
 */
void mempool_init(mempool *pool,uint32_t blockSize,uint32_t blockCount)
{
	uint32_t i;
	struct block_head *p;

	assert(blockSize >= 4);
	assert(blockCount > 1);
	
	pool->blockSize = blockSize;
	pool->blockCount = blockCount;
	
	pool->capacity = blockSize * blockCount;
	pool->addr = (uint8_t *)malloc(pool->capacity);

	pool->header = (struct block_head *)pool->addr;

	p = pool->header;
	for(i = 1;i < blockCount;i++)
	{
		p->next = (struct block_head *)(pool->addr + i*blockSize);
		p = p->next;
	}

	p->next = NULL;
}


/**
 * @brief allocation memory from mempool
 * @param pool the pool pointer
 * @retval memory pointer
 */
void *mempool_alloc(mempool *pool)
{
	void *p;
	
	p = pool->header;

	if(pool->header != NULL)
	{
		pool->blockCount--;
		pool->header = pool->header->next;
	}
	
	return p;
}


/**
 * @brief  free memory from mempool
 * @param pool the pool pointer
 * @param ptr the pointer you wanna free to pool
 * @retval None
 */
void mempool_free(mempool *pool,void *ptr)
{
	assert(ptr != NULL);

	pool->blockCount++;
	((struct block_head *)ptr)->next = pool->header;
	pool->header = ptr;
}


/**
 * @brief  detach mempool
 * @param pool the pool pointer
 * @retval None
 */
void mempool_detach(mempool *pool)
{	
	free(pool->addr);	
	
	pool->blockSize = 0;
	pool->blockCount = 0;
	pool->header = NULL;
	
	pool->capacity = 0;
	pool->addr = NULL;
}


